Skip to content

Fix: recognise Windows drive-letter absolute paths in FileFinder#36

Open
joshdaugherty wants to merge 1 commit into
pestphp:4.xfrom
joshdaugherty:fix/filefinder-windows-absolute-path
Open

Fix: recognise Windows drive-letter absolute paths in FileFinder#36
joshdaugherty wants to merge 1 commit into
pestphp:4.xfrom
joshdaugherty:fix/filefinder-windows-absolute-path

Conversation

@joshdaugherty

Copy link
Copy Markdown

What:

  • Bug Fix
  • New Feature

Description:

On Windows, running pest --mutate without an explicit --path finds nothing to mutate — it prints 0 Mutations for 0 Files created, even with a coverage driver installed.

When you don't pass --path, the plugin takes its directories from PHPUnit's <source> configuration, and PHPUnit gives those as absolute paths. FileFinder::separateDirectoriesAndFiles() then decides whether each path is relative like this:

if (! str_starts_with($path, DIRECTORY_SEPARATOR)) {
    $path = getcwd().DIRECTORY_SEPARATOR.$path;
}

On Windows, DIRECTORY_SEPARATOR is \, but an absolute Windows path begins with a drive letter such as C:\project\app — not \. So this treats the path as relative and adds getcwd() in front of it, producing a path that doesn't exist: C:\project\C:\project\app. is_dir() is then false, the directory is skipped, and the finder has nothing to scan.

This only happens on Windows. On Linux and macOS an absolute path starts with /, which is DIRECTORY_SEPARATOR, so the check works and CI never sees it. Passing a relative --path=app also avoids it, which is the usual workaround.

The fix. Add a small isAbsolutePath() check that also treats a drive-letter path (C:\... or C:/...) and a UNC path (\\server\share) as absolute — the same way PHPUnit decides this itself. Relative paths still get getcwd() added in front, so --path=app and similar keep working, and nothing changes on Linux or macOS.

Tests. A new tests/Unit/Support/FileFinderTest.php:

  • checks the new method directly for absolute paths (Unix /..., UNC, and Windows drive letters in upper and lower case) and for relative paths (including C:foo, which is relative, and an empty string), so the Windows cases are covered even when the suite runs on Linux;
  • runs FileFinder::files() against a real absolute source directory and confirms it finds the fixture files. This fails on the current 4.x on Windows (it finds nothing) and passes with the fix.

Notes.

  • Nothing changes on Linux or macOS: absolute paths still start with /, and relative paths are still resolved against getcwd().
  • The same str_starts_with($x, DIRECTORY_SEPARATOR) check is also used in FileFinder::buildPathsToIgnore() (lines 63 and 69 on 4.x), so a Windows drive-letter path in the ignore list has the same problem and may not be excluded. That is less serious than the source-path case — a missed exclusion rather than zero mutations — has no reproduction yet, and fixing it properly also means reworking the nearby getcwd() handling, so I left it out to keep this PR focused. Flagging it here; happy to follow up.
  • This edits the same line as Fix: FileFinder silently drops glob paths from phpunit source directories #23, which fixes a separate glob-pattern case just below it. The two changes are independent and apply cleanly together.
  • composer test:lint, test:types, test:refacto, test:type-coverage, and test:unit all pass.

@joshdaugherty joshdaugherty marked this pull request as ready for review June 15, 2026 15:54
A Windows absolute path starts with a drive letter (C:\...), not
DIRECTORY_SEPARATOR, so FileFinder treated PHPUnit's absolute <source>
paths as relative, prepended getcwd(), and dropped them — leaving
`pest --mutate` with nothing to mutate on Windows. Adds an
isAbsolutePath() helper (drive-letter + UNC aware, mirroring PHPUnit)
and a FileFinder test.
@joshdaugherty joshdaugherty force-pushed the fix/filefinder-windows-absolute-path branch from 603b448 to 33b45d7 Compare June 15, 2026 16:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant